<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Registries</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Registries' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inbuildn.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#2">Chapter 2: Conceptual Framework</a></li><li><b>Registries</b></li></ul></div>
<p class="purpose">Registries are nests provided with metadata and intended to be presented as an online source from which Inform resources can be downloaded.</p>

<ul class="toc"><li><a href="2-rgs.html#SP1">&#167;1. Creation</a></li><li><a href="2-rgs.html#SP3">&#167;3. The roster</a></li><li><a href="2-rgs.html#SP5">&#167;5. Building</a></li><li><a href="2-rgs.html#SP24">&#167;24. Escapology</a></li><li><a href="2-rgs.html#SP25">&#167;25. Looking up by textual ID</a></li><li><a href="2-rgs.html#SP28">&#167;28. Simpler preprocessing</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Creation.</b>To "create" a registry here does not mean actually altering the file system, for
example by making a directory: registries here are merely notes in memory of
positions in the file system hierarchy which may or may not exist.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">location</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_nest</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nest</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">roster</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inbuild_registry is accessed in 1/ic, 2/nst, 3/bg, 3/is2, 4/em, 4/ebm, 4/km, 4/lm, 4/pm, 4/tm, 5/ps2, 6/inc, 7/eip, 7/mrp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="function-syntax">Registries::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nest</span><span class="plain-syntax"> = </span><a href="2-nst.html#SP1" class="function-link"><span class="function-syntax">Nests::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"payloads"</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. The roster.</b>This is a JSON file called <span class="extract"><span class="extract-syntax">roster.json</span></span>, whose schema must match the one specified
by the file <span class="extract"><span class="extract-syntax">registry-metadata.jsonr</span></span> in the standard Inform distribution.
</p>

<p class="commentary">The following silently returns <span class="extract"><span class="extract-syntax">TRUE</span></span> if it does, or prints errors and returns
<span class="extract"><span class="extract-syntax">FALSE</span></span> if not (or if it doesn't exist).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::read_roster</span><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no registry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"roster.json"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::exists</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"%f: roster file does not exist\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"unable to read file of JSON metadata"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        &amp;</span><a href="2-jm.html#SP1" class="function-link"><span class="function-syntax">JSONMetadata::read_metadata_file_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">contents</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">tfp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TextFiles::at</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">obj</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::decode</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">contents</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">obj</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">obj</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">JSON_type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ERROR_JSONTYPE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"%f: JSON syntax error: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">obj</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_error</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP4" class="function-link"><span class="function-syntax">Registries::requirements</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">JSON::validate</span><span class="plain-syntax">(</span><span class="identifier-syntax">obj</span><span class="plain-syntax">, </span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">err</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">err</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">validation_errors</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"%f: metadata did not validate: '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">err</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> = </span><span class="identifier-syntax">obj</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The following schema validates the metadata for a registry, and is cached
so that it only needs to load once.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">dictionary</span><span class="plain-syntax"> *</span><span class="identifier-syntax">JSON_registry_metadata_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="function-syntax">Registries::requirements</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Registries::requirements</span></span>:<br/><a href="2-rgs.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">JSON_registry_metadata_requirements</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename</span><span class="plain-syntax">(</span><span class="identifier-syntax">REGISTRY_JSON_REQS_IRES</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_registry_metadata_requirements</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::read_requirements_file</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON::look_up_requirements</span><span class="plain-syntax">(</span><span class="identifier-syntax">JSON_registry_metadata_requirements</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"registry-metadata"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">req</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"JSON metadata file did not define &lt;registry-metadata&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">req</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Building.</b>To "build" a registry doesn't involve very much: just putting some indexing
files together, using the preprocessor built into <a href="../foundation/index.html" class="internal">foundation</a>.
</p>

<p class="commentary">If the registry is <span class="extract"><span class="extract-syntax">R</span></span>, we preprocess each file <span class="extract"><span class="extract-syntax">R/source/X.Y</span></span> into <span class="extract"><span class="extract-syntax">R/X.Y</span></span>:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::build</span><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no registry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ML</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-rgs.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Construct the list of custom macros for this sort of preprocessing</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"source"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Directories::listing</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">entry</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Platform::is_folder_separator</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_last_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Filenames::write_extension</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXT</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXT</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">, </span><span class="identifier-syntax">Filenames::get_leafname</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"%f -&gt; %f\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Preprocessor::preprocess</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">ML</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">STORE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="character-syntax">'#'</span><span class="plain-syntax">, </span><span class="identifier-syntax">UTF8_ENC</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construct the list of custom macros for this sort of preprocessing</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"include"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"file: LEAFNAME"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::include_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"include-css"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"?platform: PLATFORM"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP8" class="function-link"><span class="function-syntax">Registries::css_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"process"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"file: LEAFNAME"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP7" class="function-link"><span class="function-syntax">Registries::process_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"section"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP12" class="function-link"><span class="function-syntax">Registries::section_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsection"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP13" class="function-link"><span class="function-syntax">Registries::subsection_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"author"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID ?escape: WHICH"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP14" class="function-link"><span class="function-syntax">Registries::author_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID ?escape: WHICH"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP15" class="function-link"><span class="function-syntax">Registries::title_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID ?escape: WHICH"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP16" class="function-link"><span class="function-syntax">Registries::version_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"summary"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID ?escape: WHICH"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP17" class="function-link"><span class="function-syntax">Registries::summary_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"forum-thread"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP18" class="function-link"><span class="function-syntax">Registries::thread_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"section-mark"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP20" class="function-link"><span class="function-syntax">Registries::section_mark_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"section-title"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP21" class="function-link"><span class="function-syntax">Registries::section_title_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsection-mark"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP22" class="function-link"><span class="function-syntax">Registries::subsection_mark_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsection-title"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"of: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP23" class="function-link"><span class="function-syntax">Registries::subsection_title_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_loop_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP9" class="function-link"><span class="function-syntax">Registries::sections_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_loop_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"in: SECTION"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP10" class="function-link"><span class="function-syntax">Registries::subsections_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_loop_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"resources"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"in: SECTION"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP11" class="function-link"><span class="function-syntax">Registries::resources_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_loop_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"if-forum-thread"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"for: ID"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP19" class="function-link"><span class="function-syntax">Registries::if_forum_thread_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-rgs.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b><span class="extract"><span class="extract-syntax">{include file:I}</span></span> splices in the file <span class="extract"><span class="extract-syntax">R/source/include/I</span></span>, unmodified.
It can contain any textual material, and even braces and backslashes pass
through exactly as written.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::include_expander</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Registries::include_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"source"</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="string-syntax">"include"</span><span class="plain-syntax">), </span><span class="identifier-syntax">leafname</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::scan_line</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Registries::scan_line</span></span>:<br/><a href="2-rgs.html#SP8">&#167;8</a>, <a href="2-rgs.html#SP28">&#167;28</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">X</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b><span class="extract"><span class="extract-syntax">{process file:I}</span></span> also splices in the file <span class="extract"><span class="extract-syntax">R/source/include/I</span></span>, but runs
it through the preprocessor first. This means any macros it contains will be
expanded, and it has to comply with the syntax rules on use of braces and
backslash.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::process_expander</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Registries::process_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"source"</span><span class="plain-syntax">), </span><span class="identifier-syntax">I</span><span class="string-syntax">"include"</span><span class="plain-syntax">), </span><span class="identifier-syntax">leafname</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">Preprocessor::scan_line</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b><span class="extract"><span class="extract-syntax">{include-css platform:P}</span></span> splices in the Inform distribution's standard CSS
files for the named platform. It's an <span class="extract"><span class="extract-syntax">include</span></span>, not a <span class="extract"><span class="extract-syntax">process</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::css_expander</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Registries::css_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">platform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename_for_platform</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_SET_BY_PLATFORM_IRES</span><span class="plain-syntax">, </span><span class="identifier-syntax">platform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;style type=\"text/css\"&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;!--\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename_for_platform</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain-syntax">, </span><span class="identifier-syntax">platform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"--&gt;&lt;/style&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b><span class="extract"><span class="extract-syntax">{sections}</span></span> ... <span class="extract"><span class="extract-syntax">{end-sections}</span></span> is a loop construct, which loops over each
section of the registry's roster file. The loop variable <span class="extract"><span class="extract-syntax">{SECTIONID}</span></span> holds
the ID text for the section; right now, that's just <span class="extract"><span class="extract-syntax">0</span></span>, <span class="extract"><span class="extract-syntax">1</span></span>, <span class="extract"><span class="extract-syntax">2</span></span>, ...
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::sections_expander</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Registries::sections_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::set_loop_var_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"SECTIONID"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sid</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">++);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Preprocessor::add_loop_iteration</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">sid</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b><span class="extract"><span class="extract-syntax">{subsections in: SID}</span></span> ... <span class="extract"><span class="extract-syntax">{end-subsections}</span></span> loops similarly over all
subsections in the section with id <span class="extract"><span class="extract-syntax">SID</span></span>. The loop variable is <span class="extract"><span class="extract-syntax">{SUBSECTIONID}</span></span>.
This also now counts up from 0 (but textually: all preprocessor variables are
text), but note that this SSID is unique in the registry: i.e., it doesn't go back
to <span class="extract"><span class="extract-syntax">0</span></span> at the start of each section.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::subsections_expander</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Registries::subsections_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::set_loop_var_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"SUBSECTIONID"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">++);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">, </span><span class="identifier-syntax">in</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ssid</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">Preprocessor::add_loop_iteration</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">ssid</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">j</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b><span class="extract"><span class="extract-syntax">{resources in: SSID}</span></span> ... <span class="extract"><span class="extract-syntax">{end-resources}</span></span> loops similarly over all
resources in the subsection with id <span class="extract"><span class="extract-syntax">SSID</span></span>, or over absolutely all resources
if the id is given as <span class="extract"><span class="extract-syntax">ALL</span></span>. The loop variable is <span class="extract"><span class="extract-syntax">{ID}</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::resources_expander</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Registries::resources_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::set_loop_var_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ID"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">++);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">G</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">G</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">holdings</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ALL"</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">, </span><span class="identifier-syntax">in</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">Preprocessor::add_loop_iteration</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">k</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>We now have a run of macros which give details of the resource <span class="extract"><span class="extract-syntax">ID</span></span>.
</p>

<p class="commentary">First, <span class="extract"><span class="extract-syntax">{section of: ID}</span></span> produces the SID of its section.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::section_expander</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Registries::section_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">section</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">section</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">section</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b><span class="extract"><span class="extract-syntax">{subsection of: ID}</span></span> produces the SSID of its subsection.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::subsection_expander</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Registries::subsection_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subsection</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsection</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsection</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subsection</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b><span class="extract"><span class="extract-syntax">{author of: ID escape: ESC}</span></span> produces the author's name, optionally escaped
with the system below.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::author_expander</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Registries::author_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">escape</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">author</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">res</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"author"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">author</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find author"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP24" class="function-link"><span class="function-syntax">Registries::write_escaped</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">author</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b><span class="extract"><span class="extract-syntax">{title of: ID escape: ESC}</span></span> produces the title, optionally escaped with the
system below.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::title_expander</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Registries::title_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">escape</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">res</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">title</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP24" class="function-link"><span class="function-syntax">Registries::write_escaped</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b><span class="extract"><span class="extract-syntax">{version of: ID escape: ESC}</span></span> produces the version, optionally escaped with the
system below.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::version_expander</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Registries::version_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">escape</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">version</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">res</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">version</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find version"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP24" class="function-link"><span class="function-syntax">Registries::write_escaped</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">version</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b><span class="extract"><span class="extract-syntax">{summary of: ID escape: ESC}</span></span> produces the summary, optionally escaped with the
system below.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::summary_expander</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Registries::summary_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">escape</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">summary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">res</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"summary"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">summary</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find summary"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP24" class="function-link"><span class="function-syntax">Registries::write_escaped</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">summary</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b><span class="extract"><span class="extract-syntax">{thread of: ID}</span></span> produces the forum thread number, if it exists, and prints
nothing if it does not.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::thread_expander</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Registries::thread_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">res</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP25" class="function-link"><span class="function-syntax">Registries::resource_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">res</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">thread</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">res</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"forum-thread"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">thread</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">thread</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_integer</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b><span class="extract"><span class="extract-syntax">{if-forum-thread for: ID}</span></span> ... <span class="extract"><span class="extract-syntax">{end-if-forum-thread}</span></span> checks whether the
resource has a thread number, and if so, expands the material <span class="extract"><span class="extract-syntax">...</span></span>. This is
crudely done as either a 0- or 1-term loop.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::if_forum_thread_expander</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Registries::if_forum_thread_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::set_loop_var_name</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ID"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">G</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">G</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">holdings</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">++);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="identifier-syntax">of_id</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">thread</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">G</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"forum-thread"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">thread</span><span class="plain-syntax">) </span><span class="identifier-syntax">Preprocessor::add_loop_iteration</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b><span class="extract"><span class="extract-syntax">{section-mark of: SID}</span></span> produces the "section mark" of the section.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::section_mark_expander</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Registries::section_mark_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">section</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP26" class="function-link"><span class="function-syntax">Registries::section_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">mark</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">section</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mark</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b><span class="extract"><span class="extract-syntax">{section-title of: SID}</span></span> produces the title of the section.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::section_title_expander</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Registries::section_title_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">section</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP26" class="function-link"><span class="function-syntax">Registries::section_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">section</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">title</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b><span class="extract"><span class="extract-syntax">{subsection-mark of: SID}</span></span> produces the "subsection mark" of the subsection.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::subsection_mark_expander</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Registries::subsection_mark_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsection</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP27" class="function-link"><span class="function-syntax">Registries::subsection_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">mark</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsection</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mark</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b><span class="extract"><span class="extract-syntax">{subsection-title of: SID}</span></span> produces the title of the subsection.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::subsection_title_expander</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Registries::subsection_title_expander</span></span>:<br/><a href="2-rgs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_inbuild_registry</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">of</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsection</span><span class="plain-syntax"> = </span><a href="2-rgs.html#SP27" class="function-link"><span class="function-syntax">Registries::subsection_from_textual_id</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">of</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsection</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">subsection</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">title</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find title"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_string</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Escapology.</b><span class="extract"><span class="extract-syntax">quotes</span></span> escapes single quotation marks by placing a backslash before them,
as is necessary in JavaScript string literals.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">spaces</span></span> escapes spaces as <span class="extract"><span class="extract-syntax">%20</span></span>, as is necessary in URLs.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">both</span></span> does both; <span class="extract"><span class="extract-syntax">neither</span></span> does neither.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::write_escaped</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Registries::write_escaped</span></span>:<br/><a href="2-rgs.html#SP14">&#167;14</a>, <a href="2-rgs.html#SP15">&#167;15</a>, <a href="2-rgs.html#SP16">&#167;16</a>, <a href="2-rgs.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">escape</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"quotes"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\''</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'\\'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'\''</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"spaces"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%%20"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"both"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">inchar32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\''</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'\\'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="character-syntax">'\''</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%%20"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PUT</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"neither"</span><span class="plain-syntax">)) || (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">escape</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"error: no such escape as '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. Looking up by textual ID.</b>Given a textual resource id <span class="extract"><span class="extract-syntax">id</span></span>, return the JSON object for it, or else
print an error and return <span class="extract"><span class="extract-syntax">NULL</span></span>.
</p>

<p class="commentary">On success, the SID of its section is written to <span class="extract"><span class="extract-syntax">sectionid</span></span>, and the SSID
of its subsection to <span class="extract"><span class="extract-syntax">subsectionid</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="function-syntax">Registries::resource_from_textual_id</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Registries::resource_from_textual_id</span></span>:<br/><a href="2-rgs.html#SP12">&#167;12</a>, <a href="2-rgs.html#SP13">&#167;13</a>, <a href="2-rgs.html#SP14">&#167;14</a>, <a href="2-rgs.html#SP15">&#167;15</a>, <a href="2-rgs.html#SP16">&#167;16</a>, <a href="2-rgs.html#SP17">&#167;17</a>, <a href="2-rgs.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sectionid</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsectionid</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad registry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">holdings</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster holdings"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">G</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">G</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">holdings</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_id</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="identifier-syntax">this_id</span><span class="plain-syntax">)) </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_id</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">match</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sectionid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subsectionid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">G</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">k</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">j</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"error: no such resource ID as '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b>Similarly for sections, with a <span class="extract"><span class="extract-syntax">SID</span></span>.
</p>

<p class="commentary">The "mark" for a section is 1, 2, 3, ...
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="function-syntax">Registries::section_from_textual_id</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Registries::section_from_textual_id</span></span>:<br/><a href="2-rgs.html#SP20">&#167;20</a>, <a href="2-rgs.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sid</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mark</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad registry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_sid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_sid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">sid</span><span class="plain-syntax">, </span><span class="identifier-syntax">this_sid</span><span class="plain-syntax">)) </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_sid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">match</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"error: no such section ID as '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sid</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. </b>And subsections, with a <span class="extract"><span class="extract-syntax">SSID</span></span>:
</p>

<p class="commentary">The "mark" for a subsection is 1.1, 1.2, 1.3, ..., 2.1, 2.2, ...
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="function-syntax">Registries::subsection_from_textual_id</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Registries::subsection_from_textual_id</span></span>:<br/><a href="2-rgs.html#SP22">&#167;22</a>, <a href="2-rgs.html#SP23">&#167;23</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inbuild_registry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mark</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">submark</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad registry"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">roster</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">sections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> = </span><span class="identifier-syntax">JSON::look_up_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">subsections</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"could not find roster subsections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">JSON_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">subsections</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">if_list</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_ssid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_ssid</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">ssid</span><span class="plain-syntax">, </span><span class="identifier-syntax">this_ssid</span><span class="plain-syntax">)) </span><span class="identifier-syntax">match</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">this_ssid</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">match</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">mark</span><span class="plain-syntax">, </span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">submark</span><span class="plain-syntax">, </span><span class="string-syntax">"%d.%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">x</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">j</span><span class="plain-syntax">++, </span><span class="identifier-syntax">x</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">i</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"error: no such subsection ID as '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ssid</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. Simpler preprocessing.</b>A simpler version of the above preprocessor is convenient as a way of manufacting
small HTML files needed in the Inform apps: for example, to display advice text
on the launcher panels. There's nothing interesting about those files except that
they may need platform-specific CSS in order to display properly in Dark Mode,
use congenial fonts, and so on.
</p>

<p class="commentary">We preprocess from <span class="extract"><span class="extract-syntax">F</span></span> to <span class="extract"><span class="extract-syntax">T</span></span>, except that we look to see if there's a platform
variant of the file <span class="extract"><span class="extract-syntax">F</span></span> first: for example, if <span class="extract"><span class="extract-syntax">F</span></span> is <span class="extract"><span class="extract-syntax">Fruits/bananas.html</span></span>, and
the platform is <span class="extract"><span class="extract-syntax">wii</span></span>, then we look for <span class="extract"><span class="extract-syntax">Fruits/bananas-wii.html</span></span> and use that
instead. (If not, we just use <span class="extract"><span class="extract-syntax">F</span></span>.) In practice, for example, this allows the
file in the apps which lists keyboard shortcuts to vary with platform.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::preprocess_HTML</span><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">platform</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ML</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::new_macro</span><span class="plain-syntax">(</span><span class="identifier-syntax">ML</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"include-css"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"?platform: PLATFORM"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><a href="2-rgs.html#SP28" class="function-link"><span class="function-syntax">Registries::preprocess_css_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Filenames::write_unextended_leafname</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant</span><span class="plain-syntax">, </span><span class="string-syntax">"-%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">platform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Filenames::write_extension</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variant_F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">Filenames::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">), </span><span class="identifier-syntax">variant</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TextFiles::exists</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant_F</span><span class="plain-syntax">)) </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">variant_F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">variant</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"%f -&gt; %f\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Preprocessor::preprocess</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">ML</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">STORE_POINTER_text_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">platform</span><span class="plain-syntax">), </span><span class="character-syntax">'#'</span><span class="plain-syntax">, </span><span class="identifier-syntax">UTF8_ENC</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Registries::preprocess_css_expander</span><span class="plain-syntax">(</span><span class="identifier-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">platform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">platform</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">platform</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RETRIEVE_POINTER_text_stream</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename_for_platform</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_SET_BY_PLATFORM_IRES</span><span class="plain-syntax">, </span><span class="identifier-syntax">platform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;style type=\"text/css\"&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"&lt;!--\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InstalledFiles::filename_for_platform</span><span class="plain-syntax">(</span><span class="identifier-syntax">CSS_FOR_STANDARD_PAGES_IRES</span><span class="plain-syntax">, </span><span class="identifier-syntax">platform</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open include file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><a href="2-rgs.html#SP6" class="function-link"><span class="function-syntax">Registries::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"--&gt;&lt;/style&gt;\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-nst.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-gnr.html">gnr</a></li><li class="progresssection"><a href="2-wrk.html">wrk</a></li><li class="progresssection"><a href="2-edt.html">edt</a></li><li class="progresssection"><a href="2-cps.html">cps</a></li><li class="progresssection"><a href="2-ce.html">ce</a></li><li class="progresssection"><a href="2-rqr.html">rqr</a></li><li class="progresssection"><a href="2-nst.html">nst</a></li><li class="progresscurrent">rgs</li><li class="progresssection"><a href="2-jm.html">jm</a></li><li class="progresssection"><a href="2-lcn.html">lcn</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresschapter"><a href="6-st.html">6</a></li><li class="progresschapter"><a href="7-tm.html">7</a></li><li class="progressnext"><a href="2-jm.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

